import java.awt.event.KeyEvent;
import java.util.ArrayList;

public class NeuronEventProcessor extends DrawObjectEventProcessor
{
    @Override
    public void TryProcessUserKeyboardAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
    {
        if (!(KeyboardEventsToBeProcessed(GUIElements)))
            return;

        // ****************************************************************
        // 1-9 (toggle Strength of NeuronInputField 0-8)
        for (int InputFieldIndex = 0; InputFieldIndex < 9; InputFieldIndex++)
        {
            if (KeyEventProcessor.IsKeyTyped((char) ('1' + InputFieldIndex)))
            {
                if (MultiSelectionExisting)
                {
                    ArrayList<DrawObject> SelectedObjects = ObjectStorage.GetMultiSelectionObjects();

                    ObjectStorage.ToggleNeuronInputFieldByIndex(SelectedObjects, InputFieldIndex);

                    GUIElements.GetMainWindow().DoRedraw();
                }
            }
        }
        // ****************************************************************
        // h (assign Hormone to Neuron)
        if (KeyEventProcessor.IsKeyCodePressed(KeyEvent.VK_H) &&
            KeyEventProcessor.IsControlPressed())
        {
            if (GUIElements.GetMainWindow().hasFocus())
            {
                if (MultiSelectionExisting || DEFINED(NearObject))
                {
                    String HormoneName = Tools.ShowInputDialog("Hormone name? ('DEL '/'REN ' in front of existing name to remove/rename)");
                    if (HormoneName != null && HormoneName.length() >= 1)
                    {
                        boolean Del = HormoneName.toUpperCase().startsWith("DEL ");
                        boolean Ren = HormoneName.toUpperCase().startsWith("REN ");

                        String HormoneNameNew = "[internal error]";
                        if (Ren)
                        {
                            HormoneNameNew = Tools.ShowInputDialog("New Hormone name?");
                        }
                        if (Del || (Ren && HormoneNameNew != null && HormoneNameNew.length() >= 1))
                        {
                            HormoneName = HormoneName.substring(4); // remove "DEL " or "REN "

                            if (MultiSelectionExisting)
                            {
                                ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

                                for (int m = 0; m < MultiSelectionObjects.size(); m++)
                                {
                                    DrawObject o = MultiSelectionObjects.get(m);
                                    if (o.IsNeuron())
                                    {
                                        if (Del)
                                        {
                                            ((Neuron) o).DeleteHormone(HormoneName);
                                        }
                                        if (Ren)
                                        {
                                            ((Neuron) o).ReplaceHormoneName(HormoneName, HormoneNameNew);
                                        }
                                    }
                                }
                            }
                            else if (DEFINED(NearObject))
                            {
                                ArrayList<DrawObject> ObjectsContainingHormone = ObjectStorage.GetObjectsContainingHormone(HormoneName);

                                if (ObjectsContainingHormone.size() == 0)
                                {
                                    Tools.ShowMessageDialog(GUIElements.GetMainWindow(), "No such Hormone found!");
                                }
                                if (ObjectsContainingHormone.size() >= 1)
                                {
                                    if (Del)
                                    {
                                        if (ObjectsContainingHormone.size() > 1 && Tools.ShowYesNoDialog(GUIElements.GetMainWindow(), "Multiple Neurons use this Hormone. Delete from all?"))
                                        {
                                            ObjectStorage.DeleteHormoneForAll(HormoneName);
                                        }
                                        else
                                        {
                                            ((Neuron) NearObject).DeleteHormone(HormoneName);
                                        }
                                    }
                                    if (Ren)
                                    {
                                        if (ObjectsContainingHormone.size() > 1 && Tools.ShowYesNoDialog(GUIElements.GetMainWindow(), "Multiple Neurons use this Hormone. Rename in all?"))
                                        {
                                            ObjectStorage.ReplaceHormoneNameForAll(HormoneName, HormoneNameNew);
                                        }
                                        else
                                        {
                                            ((Neuron) NearObject).ReplaceHormoneName(HormoneName, HormoneNameNew);
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (MultiSelectionExisting)
                            {
                                ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

                                for (int m = 0; m < MultiSelectionObjects.size(); m++)
                                {
                                    DrawObject o = MultiSelectionObjects.get(m);
                                    if (o.IsNeuron())
                                    {
                                        if (((Neuron) o).GetHormoneStrength(HormoneName) == Double.MAX_VALUE)
                                        {
                                            ((Neuron) o).AddHormone(HormoneName);
                                        }
                                    }
                                }
                            }
                            else if (DEFINED(NearObject))
                            {
                                if (((Neuron) NearObject).GetHormoneStrength(HormoneName) == Double.MAX_VALUE)
                                {
                                    ((Neuron) NearObject).AddHormone(HormoneName);
                                }
                                else
                                {
                                    Tools.ShowMessageDialog(null, "Hormone already existing, add again with name\r\n'DEL " + HormoneName + "' to remove or 'REN " + HormoneName + "' to rename.");
                                }
                            }
                        }

                        GUIElements.GetMainWindow().DoRedraw();
                    }
                }
            }
        }
        // ****************************************************************
        // n (negate NeuronInputField)
        if (KeyEventProcessor.IsKeyTyped('n'))
        {
            if (MultiSelectionExisting)
            {
                ArrayList<DrawObject> MultiSelectionObjects = ObjectStorage.GetMultiSelectionObjects();

                for (int m = 0; m < MultiSelectionObjects.size(); m++)
                {
                    DrawObject o = MultiSelectionObjects.get(m);
                    if (o.IsSampleAndHold())
                    {
                        ((SampleAndHold) o).ToggleIsNegative();
                    }
                }

                GUIElements.GetMainWindow().DoRedraw();
            }
            else if (DEFINED(NearObject))
            {
                if (NearObject.IsNeuron())
                {
                    ((Neuron) NearObject).ToggleIsNegative(DrawObject.UnZoomPoint(MouseEventProcessor.GetMousePosPoint(GUIElements.GetMainWindow())));

                    GUIElements.GetMainWindow().DoRedraw();
                }
                if (NearObject.IsNeuronInputField()) // field is now also supported as various DrawObject looping orders changed
                {
                    ((NeuronInputField) NearObject).ToggleIsNegative();

                    GUIElements.GetMainWindow().DoRedraw();
                }
            }
        }

        return;
    }

    @Override
    public void TryProcessUserMouseAction(MainWindow.GUIElements GUIElements, KeyEventProcessor KeyEventProcessor, MouseEventProcessor MouseEventProcessor, ObjectStorage ObjectStorage, IOProgram IOProgram)
    {
        if (!(MouseEventsToBeProcessed(GUIElements)))
            return;

        // ****************************************************************
        if (MouseEventProcessor.IsRightButtonClicked())
        {
            if (DEFINED(SingleSelectedObject))
            {
                if (SingleSelectedObject.IsNeuron())
                {
                    ((Neuron) SingleSelectedObject).Toggle(DrawObject.UnZoomPoint(MouseEventProcessor.GetMousePosPoint(GUIElements.GetMainWindow())));

                    GUIElements.GetMainWindow().DoRedraw();
                }
                if (SingleSelectedObject.IsNeuronInputField()) // field is now also supported as various DrawObject looping orders changed)
                {
                    ((NeuronInputField) SingleSelectedObject).Toggle();

                    GUIElements.GetMainWindow().DoRedraw();
                }
            }
        }

        return;
    }
}
